﻿import numpy as np
import matplotlib.pyplot as plt
from scipy import optimize, integrate, interpolate, stats, linalg, fft
import warnings
warnings.filterwarnings('ignore')

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']  # 使用黑体
plt.rcParams['axes.unicode_minus'] = False    # 解决负号显示问题

# 创建可视化图表
fig, axes = plt.subplots(2, 3, figsize=(15, 10))
fig.suptitle('SciPy 综合使用示例', fontsize=16)

# 1. 优化 - 寻找函数最小值
def f(x):
    return x**2 + 10*np.sin(x)

x = np.linspace(-10, 10, 100)
axes[0, 0].plot(x, f(x), label='f(x) = x² + 10sin(x)')
result = optimize.minimize(f, x0=0)
axes[0, 0].plot(result.x, result.fun, 'ro', label='最小值点')
axes[0, 0].set_title('优化: 寻找函数最小值')
axes[0, 0].legend()
axes[0, 0].grid(True)

# 2. 积分 - 计算定积分
def integrand(x):
    return np.exp(-x**2)

x = np.linspace(-3, 3, 100)
axes[0, 1].plot(x, integrand(x), label='e^(-x²)')
result, error = integrate.quad(integrand, -np.inf, np.inf)
axes[0, 1].set_title(f'积分: ∫e^(-x²)dx = {result:.3f}')
axes[0, 1].fill_between(x, integrand(x), alpha=0.3)
axes[0, 1].legend()
axes[0, 1].grid(True)

# 3. 插值 - 从稀疏数据点重建函数
x = np.linspace(0, 10, 10)
y = np.sin(x)
x_new = np.linspace(0, 10, 100)
f_interp = interpolate.interp1d(x, y, kind='cubic')
axes[0, 2].plot(x, y, 'o', label='原始数据')
axes[0, 2].plot(x_new, f_interp(x_new), '--', label='插值结果')
axes[0, 2].set_title('插值: 从稀疏点重建函数')
axes[0, 2].legend()
axes[0, 2].grid(True)

# 4. 统计 - 概率分布
mu, sigma = 0, 1
x = np.linspace(-5, 5, 100)
pdf = stats.norm.pdf(x, mu, sigma)
axes[1, 0].plot(x, pdf, label='正态分布')
axes[1, 0].set_title('统计: 概率密度函数')
axes[1, 0].fill_between(x, pdf, alpha=0.3)
axes[1, 0].legend()
axes[1, 0].grid(True)

# 5. 线性代数 - 矩阵操作和求解
A = np.array([[3, 2, 0], [1, -1, 0], [0, 5, 1]])
b = np.array([2, 4, -1])
x = linalg.solve(A, b)
axes[1, 1].imshow(A, cmap='viridis', interpolation='nearest')
axes[1, 1].set_title(f'线性代数: 解方程组\n解: {x}')
for i in range(A.shape[0]):
    for j in range(A.shape[1]):
        axes[1, 1].text(j, i, f'{A[i, j]}', ha='center', va='center', color='w')

# 6. 傅里叶变换 - 信号处理
t = np.linspace(0, 1, 1000)
signal = np.sin(2*np.pi*5*t) + 0.5*np.sin(2*np.pi*10*t)
f_signal = fft.fft(signal)
freq = fft.fftfreq(len(t), t[1]-t[0])
axes[1, 2].plot(t, signal, label='原始信号')
axes[1, 2].plot(freq, np.abs(f_signal), label='频谱')
axes[1, 2].set_xlim(-15, 15)
axes[1, 2].set_title('傅里叶变换: 信号分析')
axes[1, 2].legend()
axes[1, 2].grid(True)

plt.tight_layout()
plt.show()